package com.fs.activiti5.extend;

/**
 * @author Administrator
 *
 */
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior;
import org.activiti.engine.impl.javax.el.ExpressionFactory;
import org.activiti.engine.impl.javax.el.ValueExpression;
import org.activiti.engine.impl.juel.ExpressionFactoryImpl;
import org.activiti.engine.impl.juel.SimpleContext;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.fs.activiti5.service.ActivitiService;
import com.fs.base.utils.ApplicationUtils;
import com.fs.flow.pojo.FlowCondition;
import com.fs.flow.repository.FlowConditionRepository;
/** 
 * 对网关的条件判断，优先使用扩展的配置 
 * @author keitch 
 * 
 */  
@Component
@SuppressWarnings("serial")  
public class ExclusiveGatewayActivityBehaviorExt extends ExclusiveGatewayActivityBehavior{  
      
    protected static Logger log = LoggerFactory.getLogger(ExclusiveGatewayActivityBehaviorExt.class);  
   /* public static void main(String[] args) throws Exception {
        //String el = "${请假天数>3 && 部门 == '产品部'}";
        String el = "${a>100}";
        Map<String, Object> formData = new HashMap<>();
        formData.put("请假天数", 2);
        formData.put("部门", "产品部");
        formData.put("test", "123");
        formData.put("a", "000022");
        
        System.out.println(checkJuel(el, formData));
    }*/
   
    protected Boolean checkJuel(String juel, Map<String, Object> variables) throws Exception {
        ExpressionFactory factory = new ExpressionFactoryImpl();
        SimpleContext context = new SimpleContext();
        for (Object k : variables.keySet()) {
            if (variables.get(k) != null) {
                context.setVariable(k.toString(), factory.createValueExpression(variables.get(k), variables.get(k).getClass()));
            }
        }
        ValueExpression e = factory.createValueExpression(context, juel, Boolean.class);
        return (Boolean) e.getValue(context);
    }
    
    protected void leave(ActivityExecution execution) {
    	FlowConditionRepository flowConditionRepository = (FlowConditionRepository) ApplicationUtils.getBean("flowConditionRepository");
    	ActivitiService activitiService = (ActivitiService) ApplicationUtils.getBean("activitiService");
    	RuntimeService runtimeService = activitiService.getRuntimeService();
    	Map<String, Object> variables = runtimeService.getVariables(execution.getId());
    	
    	if (log.isDebugEnabled()) {
          log.debug("Leaving activity '{}'", execution.getActivity().getId());
        }
        String processKey = execution.getProcessDefinitionId().split(":")[0];
       
        String seqFlowId = null;
        String taskId = null;
        FlowCondition fCondition = null;
        PvmTransition outgoingSeqFlow = null;
        Iterator<PvmTransition> transitionIterator = execution.getActivity().getOutgoingTransitions().iterator();
        while (outgoingSeqFlow == null && transitionIterator.hasNext()) {
          PvmTransition seqFlow = transitionIterator.next();
          seqFlowId = seqFlow.getId();
          taskId = seqFlow.getSource().getId();
          
          System.out.println("taskId: "+ taskId);
          System.out.println("seqFlow: "+ seqFlowId);
          System.out.println("processKey:"+ processKey);
          
          String express = "";
          fCondition = flowConditionRepository.findByProcessKeyAndTaskIdAndSequenceFlowId(processKey, taskId, seqFlowId);
          if(fCondition!=null&& StringUtils.isNotBlank(fCondition.getExpress())){
        	  express = fCondition.getExpress();
        	  express = "${".concat(express).concat("}");
          }
	      try {
				Boolean flag = checkJuel(express, variables);
				if(flag){
					outgoingSeqFlow = seqFlow;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
        }
        
        if (outgoingSeqFlow != null) {
          execution.take(outgoingSeqFlow);
        } else {
        	super.leave(execution);
        }
      }

    }